#define GPH0CON		0xE0200C00
#define GPH0DAT		0xE0200C04
#define GPH2CON		0xE0200C40
#define GPH2DAT		0xE0200C44
 
#define rGPH0CON	(*(volatile unsigned int *)GPH0CON)
#define rGPH0DAT	(*(volatile unsigned int *)GPH0DAT)
#define rGPH2CON	(*(volatile unsigned int *)GPH2CON)
#define rGPH2DAT	(*(volatile unsigned int *)GPH2DAT)
 
#define EXT_INT_0_CON	0xE0200E00
#define EXT_INT_2_CON	0xE0200E08
#define EXT_INT_0_PEND	0xE0200F40
#define EXT_INT_2_PEND	0xE0200F48
#define EXT_INT_0_MASK	0xE0200F00
#define EXT_INT_2_MASK	0xE0200F08
 
#define rEXT_INT_0_CON	(*(volatile unsigned int *)EXT_INT_0_CON)
#define rEXT_INT_2_CON	(*(volatile unsigned int *)EXT_INT_2_CON)
#define rEXT_INT_0_PEND	(*(volatile unsigned int *)EXT_INT_0_PEND)
#define rEXT_INT_2_PEND	(*(volatile unsigned int *)EXT_INT_2_PEND)
#define rEXT_INT_0_MASK	(*(volatile unsigned int *)EXT_INT_0_MASK)
#define rEXT_INT_2_MASK	(*(volatile unsigned int *)EXT_INT_2_MASK)


// 以中断方式来处理按键的初始化 
void key_init_interrupt(void)
{
	// 1. 外部中断对应的GPIO模式设置
 	rGPH0CON |= 0xFF<<0;		// GPH0_0 GPH0_1设置为外部中断模式
	//rGPH2CON |= 0xFFFF<<0;		// GPH2_0123共4个引脚设置为外部中断模式
		
	// 2. 中断触发模式设置
	rEXT_INT_0_CON &= ~(0xFF<<0);	// bit0~bit7全部清零
	rEXT_INT_0_CON |= ((2<<0)|(2<<4));		// EXT_INT2和EXT_INT3设置为下降沿触发
	//rEXT_INT_2_CON &= ~(0xFFFF<<0);
	//rEXT_INT_2_CON |= ((2<<0)|(2<<4)|(2<<8)|(2<<12));	
								
	// 3. 中断允许
	rEXT_INT_0_MASK &= ~(3<<0);			// 外部中断允许
	//rEXT_INT_2_MASK &= ~(0x0f<<0);
									
	// 4. 清挂起，清除是写1，不是写0
	rEXT_INT_0_PEND |= (3<<0);
	//rEXT_INT_2_PEND |= (0x0F<<0);
}

// EINT2通道对应的按键，就是GPH0_2引脚对应的按键，就是开发板上标了LEFT的那个按键
void isr_eint0()
{
	// 真正的isr应该做2件事情。
	// 第一，中断处理代码，就是真正干活的代码
	//printf("isr_eint2_LEFT.\n");
    __asm__( 
    
    "ldr sp, = 0xD0037F80\n"
    "sub lr, lr, #4\n"  
    "stmfd sp!, {r0-r12, lr}\n"       
    : 
    : 
   );

	putc('a');
	led_off(0);
	led_off(1);
	led_off(2);
	led_off(3);
	led_on(0);

	// 第二，清除中断挂起(中断处理后，必须清除中断挂起)
	rEXT_INT_0_PEND |= (1<<0);
	intc_clearvectaddr();//清除需要处理的中断的中断处理函数的地址
    __asm__(
    "ldmfd sp!, {r0-r12, pc}^ \n"       
    : 
    : 
  );
   
}


void isr_eint1()
{
	// 真正的isr应该做2件事情。
	// 第一，中断处理代码，就是真正干活的代码
	//printf("isr_eint3_DOWN.\n");
    __asm__( 
    
    "ldr sp, = 0xD0037F80\n"
    "sub lr, lr, #4\n"  
    "stmfd sp!, {r0-r12, lr}\n"       
    : 
    : 
   );
	led_off(0);
	led_off(1);
	led_off(2);
	led_off(3);
	led_on(2);
	putc('b');
	// 第二，清除中断挂起
	rEXT_INT_0_PEND |= (1<<1);
	intc_clearvectaddr();// 清除需要处理的中断的中断处理函数的地址
    __asm__(
    "ldmfd sp!, {r0-r12, pc}^ \n"       
    : 
    : 
  );
}
void irq_handler1()
{
	volatile unsigned char key_code = intc_getvicirqstatus(0)&0x3;
	if(key_code ==1)
	{
	    led_on(0);
	    putc('c');
	}
	else if(key_code ==2)
	{
	    led_on(1);
	    putc('d');
	}
	else
	{
	    led_on(2);
	    putc('e');
	}
	intc_clearvectaddr();
	rEXT_INT_0_PEND =~0x0;
}
/*void isr_eint16171819(void)
{
	// 真正的isr应该做2件事情。
	// 第一，中断处理代码，就是真正干活的代码
	// 因为EINT16～31是共享中断，所以要在这里再次去区分具体是哪个子中断
	if (rEXT_INT_2_PEND & (1<<0))
	{
		printf("eint16\n");
	}
	if (rEXT_INT_2_PEND & (1<<1))
	{
		printf("eint17\n");
	}
	if (rEXT_INT_2_PEND & (1<<2))
	{
		printf("eint18\n");
	}
	if (rEXT_INT_2_PEND & (1<<3))
	{
		printf("eint19\n");
	}
	// 第二，清除中断挂起
	rEXT_INT_2_PEND |= (0x0f<<0);
	intc_clearvectaddr();
}*/

